/*****************************************************************************
 * file  : test.c
 * creat : apleilx
 * data  : 2017/03/02
 *******************************************************************************/
#define __os_obj_creat__ // define objects in rtxapp module
#include "os_obj.h"		 // RTOS object definitions
#include "framework.h"
#include "bsp_api.h"
#include "mem_alloc.h"

void task_system(const void *argument);
void modbus_task(void const *argument);
void usb_task(void const *argument);
void task_console(void const *argument);
void gui_task(void const *argument);

// 独立堆栈 需定义
osThreadDef(usb_task, osPriorityLow, 1, 0x800);
osThreadDef(task_console, osPriorityLow7, 1, 0x400);
osThreadDef(gui_task, osPriorityLow3, 1, 0x400);
osThreadDef(modbus_task, osPriorityAboveNormal, 1, 0x200);
osThreadDef(task_system, osPriorityHigh, 1, 0x400);	

osMutexDef(eep_mutex);

osMutexDef(printf_mutex);
osMutexDef(malloc_mutex);
osMutexDef(file_mutex);

/*----------------------------------------------------------------------------
 *      systask , create befor os start
 *---------------------------------------------------------------------------*/
int thread_init(void)
{
	// 系统对象创建
	os_obj.mid_file = osMutexCreate(osMutex(file_mutex));
	os_obj.mid_printf = osMutexCreate(osMutex(printf_mutex));
	os_obj.mid_malloc = osMutexCreate(osMutex(malloc_mutex));

	// 系统任务创建
	os_obj.tid_sys_task = osThreadCreate(osThread(task_system), NULL);

	return (0);
}

/*----------------------------------------------------------------------------
 *   created in systask
 *---------------------------------------------------------------------------*/
int thread_create(void)
{
	// 任务创建
	os_obj.tid_console_task = osThreadCreate(osThread(task_console), NULL);
	os_obj.tid_usb_task = osThreadCreate(osThread(usb_task), NULL);
	os_obj.tid_gui_task = osThreadCreate(osThread(gui_task), NULL);
	os_obj.tid_mb_task = osThreadCreate(osThread(modbus_task), NULL);
	
	return (0);
}

/*----------------------------------------------------------------------------
 *   os lock
 *---------------------------------------------------------------------------*/
void os_lock(void)
{
	osKernelLock();
}

void os_unlock(void)
{
	osKernelUnlock();
}

/*----------------------------------------------------------------------------
 *   task info print
 *---------------------------------------------------------------------------*/
void os_task_info_print(osThreadId tid, const char *name)
{
	int stk, stk_used, pused, prio;

	if (!tid)
		return;

	stk = osThreadGetStackSize(tid);
	stk_used = stk - osThreadGetStackSpace(tid);
	pused = stk_used * 100 / stk;
	prio = osThreadGetPriority(tid);

	dbg_print("stack size: %05x, stack used: %5x, <%02d%%>, prio : %2d, name: %s\n",
			  stk,
			  stk_used,
			  pused,
			  prio,
			  name);

	(void)pused;
	(void)prio;
}

void os_task_info(void)
{
	dbg_puts(SYMBOL_LINE_EQ PTCR);
	
	dbg_print("system stack used : %d %%\n", stack_used() / 10);
	dbg_print("system heap used  : %d %%\n", mem_sram.info->used_max*100 / mem_sram.block_amount);
	dbg_print("task amount : %d \n", osThreadGetCount());

	os_task_info_print(os_obj.tid_sys_task, "sys task");
	os_task_info_print(os_obj.tid_gui_task, "gui task");
	os_task_info_print(os_obj.tid_key_task, "key task");
	os_task_info_print(os_obj.tid_console_task, "console task");
	os_task_info_print(os_obj.tid_flash_task, "flash task");
	os_task_info_print(os_obj.tid_mb_task, "modbus task");
	os_task_info_print(os_obj.tid_str_task, "str task");
	os_task_info_print(os_obj.tid_usb_task, "usb task");
	os_task_info_print(os_obj.tid_hist, "history task");
}

int task_list(int argc, char *argv[])
{
	os_task_info();
	
	return 0;
}
DBG_FUN_EXPORT(task_list);
